<template>
    <!-- 定义搜索框 -->
    <lemon-search :form-model="searchFormModel" :form-item="searchFormItem" :show-search="true" :show-add="true" search-permission="PAGE" add-permission="INSERT" @on-search="onSearch" @on-add="onAdd">
        <template #afterBtn>
            <el-button type="success" size="default" :icon="Download" v-has-permission="'EXPORTTEMPLATE'" @click="onExport">导出模板</el-button>
            <el-button type="success" size="default" :icon="artificialIntelligence" v-has-permission="'GENERATEPAPER'" @click="onGeneratePaper">AI生成</el-button>
        </template>
    </lemon-search>

    <!-- 数据表格 -->
    <lemon-table :data="data?.content" height="calc(100vh - 196px)" :table-item="tableItem" :show-enable="false" :show-unable="false" @on-info="onInfo" @on-edit="onEdit" @on-del="onDel">
        <template #frontBtn="scope">
            <el-button type="success" size="default" @click="onFindQuestion(scope.row)" v-has-permission="'FINDPAPERQUESTION'">试题</el-button>
        </template>
    </lemon-table>

    <!-- 分页 -->
    <lemon-page :data="data" @on-size-change="onSizeChange" @on-current-change="onCurrentChange" />

    <!-- 添加弹窗 -->
    <lemon-dialog v-model="dialogAdd" dialog-title="添加" :dialog-footer="true" @on-submit="onAddSubmit" @on-cancel="onAddCancel" @on-before-close="onAddCancel">
        <el-form ref="addFormRef" :model="addForm" label-width="90px" class="lemon-form-class">
            <el-form-item label="班级" prop="classId" :rules="rule.require.select('班级')">
                <el-tree-select v-model="addForm.classId" :data="classOptions" @node-click="onNodeSelect" placeholder="请选择班级" :render-after-expand="false" style="width: 100%" size="default" />
            </el-form-item>
            <el-form-item label="试卷名称" prop="name" :rules="rule.require.input('试卷名称')">
                <el-input v-model="addForm.name" style="width: 100%" placeholder="请输入试卷名称" clearable size="default" />
            </el-form-item>
            <el-form-item label="考试说明">
                <el-input v-model="addForm.remark" type="textarea" :rows="3" style="width: 100%" placeholder="请输入考试说明" clearable size="default" />
            </el-form-item>
            <el-form-item label="开始时间" prop="startTime" :rules="rule.require.select('开始时间')">
                <el-date-picker v-model="addForm.startTime" type="datetime" placeholder="请选择考试开始时间" format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" style="width: 100%" clearable size="default" @change="onStartTimeChange" />
            </el-form-item>
            <el-form-item label="结束时间" prop="endTime" :rules="rule.require.select('结束时间')">
                <el-date-picker v-model="addForm.endTime" type="datetime" placeholder="请选择考试结束时间" format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" style="width: 100%" clearable size="default" @change="onEndTimeChange" />
            </el-form-item>
            <el-form-item label="考试时长" v-if="addFormDurationShow">
                <el-input v-model="addForm.duration" style="width: 100%; pointer-events: none" size="default">
                    <template #append>分钟</template>
                </el-input>
            </el-form-item>
            <el-form-item label="查看答案" prop="lookAnswer" :rules="rule.require.select('结束后查看答案')">
                <el-tooltip class="box-item" effect="dark" content="考试结束后是否允许查看答案" placement="top-start">
                    <el-switch v-model="addForm.lookAnswer" inline-prompt style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949" active-text="是" inactive-text="否" :active-value="1" :inactive-value="0" />
                </el-tooltip>
            </el-form-item>
            <el-form-item label="打乱试题" prop="upset" :rules="rule.require.select('打乱试题')">
                <el-switch v-model="addForm.upset" inline-prompt style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949" active-text="是" inactive-text="否" :active-value="1" :inactive-value="0" />
            </el-form-item>
            <el-form-item label="及格分数" prop="passScore" :rules="rule.require.input('及格分数')">
                <el-input-number v-model="addForm.passScore" placeholder="请输入及格分数" controls-position="right" size="default" style="width: 100%" />
            </el-form-item>
            <el-form-item label="试卷总分" v-if="addFormTotalScoreShow">
                <el-input v-model="addForm.totalScore" style="width: 100%; pointer-events: none" size="default" />
            </el-form-item>
            <el-form-item label="上传试卷" prop="filePath" :rules="rule.require.input('上传试卷')">
                <el-upload class="upload-paper" :limit="1" :multiple="false" drag :on-success="onSuccess" :http-request="onUpload" :before-upload="onBeforeUpload">
                    <el-icon class="el-icon--upload"><upload-filled /></el-icon>
                    <template #tip>
                        <div class="el-upload__tip"></div>
                    </template>
                </el-upload>
            </el-form-item>
        </el-form>
    </lemon-dialog>

    <!-- 详情弹窗 -->
    <lemon-dialog v-model="dialogInfo" dialog-title="详情" @on-before-close="onInfoCancel">
        <el-form :model="infoForm" label-width="90px" class="lemon-form-class">
            <el-form-item label="班级">
                <el-tree-select v-model="infoForm.classId" :data="classOptions" placeholder="请选择班级" :render-after-expand="false" style="width: 100%; pointer-events: none" size="default" />
            </el-form-item>
            <el-form-item label="试卷名称">
                <el-input v-model="infoForm.name" style="width: 100%; pointer-events: none" size="default" />
            </el-form-item>
            <el-form-item label="考试说明">
                <el-input v-model="infoForm.remark" type="textarea" :rows="3" style="width: 100%; pointer-events: none" size="default" />
            </el-form-item>
            <el-form-item label="开始时间">
                <el-date-picker v-model="infoForm.startTime" type="datetime" format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" style="width: 100%; pointer-events: none" size="default" />
            </el-form-item>
            <el-form-item label="结束时间">
                <el-date-picker v-model="infoForm.endTime" type="datetime" format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" style="width: 100%; pointer-events: none" size="default" />
            </el-form-item>
            <el-form-item label="考试时长">
                <el-input v-model="infoForm.duration" style="width: 100%; pointer-events: none" size="default">
                    <template #append>分钟</template>
                </el-input>
            </el-form-item>
            <el-form-item label="查看答案">
                <el-switch v-model="infoForm.lookAnswer" inline-prompt style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949; pointer-events: none" active-text="是" inactive-text="否" :active-value="1" :inactive-value="0" />
            </el-form-item>
            <el-form-item label="打乱试题">
                <el-switch v-model="infoForm.upset" inline-prompt style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949; pointer-events: none" active-text="是" inactive-text="否" :active-value="1" :inactive-value="0" />
            </el-form-item>
            <el-form-item label="及格分数">
                <el-input-number v-model="infoForm.passScore" controls-position="right" size="default" style="width: 100%; pointer-events: none" />
            </el-form-item>
            <el-form-item label="试卷总分">
                <el-input v-model="infoForm.totalScore" style="width: 100%; pointer-events: none" size="default" />
            </el-form-item>
            <el-form-item label="上传试卷">
                <el-tooltip class="box-item" effect="dark" content="点击下载" placement="top-start" v-if="hasPermission('DOWNLOAD')">
                    <span class="dialog-paper-download" @click="onDownload(infoForm.id)">{{ infoForm.originFileName }}</span>
                </el-tooltip>
                <span class="dialog-paper-download" v-else>{{ infoForm.originFileName }}</span>
            </el-form-item>
        </el-form>
    </lemon-dialog>

    <!-- 编辑弹窗 -->
    <lemon-dialog v-model="dialogEdit" dialog-title="编辑" :dialog-footer="true" @on-submit="onEditSubmit" @on-cancel="onEditCancel" @on-before-close="onEditCancel">
        <el-form ref="addFormRef" :model="addForm" label-width="90px" class="lemon-form-class">
            <el-form-item label="班级" prop="classId" :rules="rule.require.select('班级')">
                <el-tree-select v-model="addForm.classId" :data="classOptions" @node-click="onNodeSelect" placeholder="请选择班级" :render-after-expand="false" style="width: 100%" size="default" />
            </el-form-item>
            <el-form-item label="试卷名称" prop="name" :rules="rule.require.input('试卷名称')">
                <el-input v-model="addForm.name" style="width: 100%" placeholder="请输入试卷名称" clearable size="default" />
            </el-form-item>
            <el-form-item label="考试说明">
                <el-input v-model="addForm.remark" type="textarea" :rows="3" style="width: 100%" placeholder="请输入考试说明" clearable size="default" />
            </el-form-item>
            <el-form-item label="开始时间" prop="startTime" :rules="rule.require.select('开始时间')">
                <el-date-picker v-model="addForm.startTime" type="datetime" placeholder="请选择考试开始时间" format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" style="width: 100%" clearable size="default" @change="onStartTimeChange" />
            </el-form-item>
            <el-form-item label="结束时间" prop="endTime" :rules="rule.require.select('结束时间')">
                <el-date-picker v-model="addForm.endTime" type="datetime" placeholder="请选择考试结束时间" format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" style="width: 100%" clearable size="default" @change="onEndTimeChange" />
            </el-form-item>
            <el-form-item label="考试时长">
                <el-input v-model="addForm.duration" style="width: 100%; pointer-events: none" size="default">
                    <template #append>分钟</template>
                </el-input>
            </el-form-item>
            <el-form-item label="查看答案" prop="lookAnswer" :rules="rule.require.select('结束后查看答案')">
                <el-tooltip class="box-item" effect="dark" content="考试结束后是否允许查看答案" placement="top-start">
                    <el-switch v-model="addForm.lookAnswer" inline-prompt style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949" active-text="是" inactive-text="否" :active-value="1" :inactive-value="0" />
                </el-tooltip>
            </el-form-item>
            <el-form-item label="打乱试题" prop="upset" :rules="rule.require.select('打乱试题')">
                <el-switch v-model="addForm.upset" inline-prompt style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949" active-text="是" inactive-text="否" :active-value="1" :inactive-value="0" />
            </el-form-item>
            <el-form-item label="及格分数" prop="passScore" :rules="rule.require.input('及格分数')">
                <el-input-number v-model="addForm.passScore" placeholder="请输入及格分数" controls-position="right" size="default" style="width: 100%" />
            </el-form-item>
            <el-form-item label="试卷总分">
                <el-input v-model="addForm.totalScore" style="width: 100%; pointer-events: none" size="default" />
            </el-form-item>
            <el-form-item label="上传试卷" prop="filePath" :rules="rule.require.input('上传试卷')">
                <el-upload class="upload-paper" :limit="1" :multiple="false" drag :on-success="onSuccess" :http-request="onUpload" :before-upload="onBeforeUpload">
                    <span class="dialog-paper-download">{{ addForm.originFileName }}</span>
                    <template #tip>
                        <div class="el-upload__tip"></div>
                    </template>
                </el-upload>
            </el-form-item>
        </el-form>
    </lemon-dialog>

    <!-- 试卷详情弹窗 -->
    <lemon-dialog v-model="dialogQuestion" :dialog-title="dialogPaperName" dialogWidth="50%" @on-cancel="dialogQuestion = false" @on-before-close="dialogQuestion = false">
        <paper-question-list :questionList="questionList" />
    </lemon-dialog>

    <!-- AI生成试卷弹窗 -->
    <lemon-dialog v-model="dialogPaperGenerate" dialog-title="AI生成试卷" :dialog-footer="true" :dialog-show-submit-btn="dialogPaperGenerateSubmitBtn" @on-submit="onPaperGenerateSubmit" @on-cancel="onPaperGenerateCancel" @on-before-close="onPaperGenerateCancel">
        <paper-generate-form ref="paperGenerateFormRef" @on-generate-over="onGenerateOver" />
        <template #frontBtn>
            <el-button v-if="dialogPaperGenerateInfoBtn" type="success" @click="onPaperGeneratePaperInfo">查看</el-button>
            <el-button v-if="dialogPaperGenerateInfoBtn" type="warning" @click="onPaperGeneratePaperDownload">下载</el-button>
        </template>
    </lemon-dialog>
</template>

<script setup lang="ts">
import { reactive, inject, ref, onMounted, onUnmounted } from "vue";
import { dayjs, type FormInstance } from "element-plus";
import { debounce } from "lodash-es";
import { Download } from "@element-plus/icons-vue";
import { boolFormat, hasPermission, artificialIntelligence } from "@/utils/common";
import PaperQuestionList from "@/views/system/components/paper/PaperQuestionList.vue";
import PaperGenerateForm from "@/views/system/components/paper/PaperGenerateForm.vue";

//获取自定义全局方法
const { rule, http, box, emitter } = inject<any>("method");

//班级选择的对象
const classOptions = ref<any[]>([]);

//表格数据
const data = ref<any>();

//分页信息（页码，分页数量）
const page = reactive({
    pageNum: 1,
    pageSize: 10,
});

//搜索的form
const searchFormModel = reactive({
    classId: null,
    name: "",
});

//搜索form子项
const searchFormItem = reactive({
    classId: { label: "班级", type: "tree-select", options: classOptions },
    name: { label: "名称", type: "input" },
});

//表格每一项
const tableItem = reactive([
    { prop: "className", label: "班级", minWidth: "150" },
    { prop: "name", label: "名称", minWidth: "150" },
    { prop: "remark", label: "考试说明", minWidth: "250" },
    { prop: "startTime", label: "开始考试时间", minWidth: "200" },
    { prop: "endTime", label: "结束考试时间", minWidth: "200" },
    { prop: "duration", label: "时长（分钟）", minWidth: "120" },
    { prop: "lookAnswer", label: "是否允许查看答案", minWidth: "150", formatter: boolFormat },
    { prop: "upset", label: "是否打乱试题", minWidth: "120", formatter: boolFormat },
    { prop: "passScore", label: "及格分数", minWidth: "100" },
    { prop: "totalScore", label: "试卷总分", minWidth: "100" },
    { prop: "createBy", label: "创建人", minWidth: "150" },
    { prop: "createTime", label: "创建时间", minWidth: "200" },
]);

//搜索
const onSearch = () => init();

//展示添加弹窗
const dialogAdd = ref<boolean>(false);

//添加Form
const addFormRef = ref<FormInstance>();

const addForm = reactive<any>({
    id: null,
    gradeId: null,
    classId: null,
    name: "",
    remark: "",
    startTime: null,
    endTime: null,
    duration: "",
    lookAnswer: 1,
    upset: 1,
    passScore: null,
    totalScore: null,
    originFileName: "",
    newFileName: "",
    filePath: "",
});

//添加时长是否显示
const addFormDurationShow = ref<boolean>(false);

//添加时长是否显示
const addFormTotalScoreShow = ref<boolean>(false);

const onStartTimeChange = (value: any) => {
    if (value) {
        const start = new Date(value);
        const now = new Date();
        if (start.getTime() < now.getTime()) {
            emitter.emit("msg-error", { message: "开始时间不能小于当前时间", duration: 3000 });
            addForm.startTime = null;
        } else if (addForm.endTime) {
            const end = new Date(addForm.endTime);
            if (start.getTime() >= end.getTime()) {
                emitter.emit("msg-error", { message: "结束时间必须大于开始时间", duration: 3000 });
                addForm.startTime = null;
            } else {
                const diffInMinutes = dayjs(end).diff(dayjs(start), "minute");
                addFormDurationShow.value = true;
                addForm.duration = diffInMinutes.toString();
            }
        }
    }
};

const onEndTimeChange = (value: any) => {
    if (value) {
        const end = new Date(value);
        const now = new Date();
        if (end.getTime() < now.getTime()) {
            emitter.emit("msg-error", { message: "结束时间不能小于当前时间", duration: 3000 });
            addForm.endTime = null;
        } else if (addForm.startTime) {
            const start = new Date(addForm.startTime);
            if (start.getTime() >= end.getTime()) {
                emitter.emit("msg-error", { message: "结束时间必须大于开始时间", duration: 3000 });
                addForm.endTime = null;
            } else {
                const diffInMinutes = dayjs(end).diff(dayjs(start), "minute");
                addFormDurationShow.value = true;
                addForm.duration = diffInMinutes.toString();
            }
        }
    }
};

//添加
const onAdd = () => {
    addForm.gradeId = null;
    addForm.classId = null;
    addForm.name = "";
    addForm.remark = "";
    addForm.startTime = null;
    addForm.endTime = null;
    addForm.duration = "";
    addForm.lookAnswer = 1;
    addForm.upset = 1;
    addForm.passScore = null;
    addForm.totalScore = null;
    addForm.originFileName = "";
    addForm.newFileName = "";
    addForm.filePath = "";
    addFormDurationShow.value = false;
    addFormTotalScoreShow.value = false;
    dialogAdd.value = true;
};

//树形选择完成后
const onNodeSelect = (_nodeData: any, node: any) => {
    addForm.gradeId = node.parent.data.value;
};

//上传成功
const onSuccess = () => {
    addFormTotalScoreShow.value = true;
    emitter.emit("msg-success", "上传成功");
};

//上传之前
const onBeforeUpload = (file: any) => {
    if (file.type !== "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") {
        emitter.emit("msg-error", "请上传excel文件！");
        return false;
    }
    return true;
};

//执行上传
const onUpload = async (file: any) => {
    const data = await http.upload("paper/upload", file.file);
    if (data?.success) {
        addForm.totalScore = data?.data?.totalScore;
        addForm.originFileName = data?.data?.originFileName;
        addForm.newFileName = data?.data?.newFileName;
        addForm.filePath = data?.data?.filePath;
        addFormTotalScoreShow.value = true;
    }
};

//试卷弹窗
const dialogQuestion = ref<boolean>(false);

const dialogPaperName = ref<string>("");

//试题数据
const questionList = ref<Array<any>>([]);

//查看试题
const onFindQuestion = async (row: any) => {
    dialogPaperName.value = row?.name ? row.name : "未命名";
    questionList.value = await http.get(`paper/findPaperQuestion/${row.id}`);
    dialogQuestion.value = true;
};

//添加弹窗->提交
const onAddSubmit = async () => {
    if (!addFormRef.value) return;
    const status = await addFormRef.value?.validate((valid: any, _fields: any) => valid);
    if (status) {
        const data = await http.post("paper/insert", addForm);
        if (data?.success) {
            emitter.emit("msg-success", data?.data);
            init();
            onAddCancel();
        }
    }
};

//添加弹窗->取消
const onAddCancel = () => {
    dialogAdd.value = false;
    addFormRef.value?.resetFields();
};

//防抖导出模板
const onExport = debounce(async () => await http.export("paper/exportTemplate"), 200);

//详情
const infoForm = reactive<any>({
    id: null,
    gradeId: null,
    classId: null,
    name: "",
    remark: "",
    startTime: null,
    endTime: null,
    duration: "",
    lookAnswer: 1,
    upset: 1,
    passScore: null,
    totalScore: null,
    originFileName: "",
    newFileName: "",
    filePath: "",
});

//展示详情弹窗
const dialogInfo = ref<boolean>(false);
//详情
const onInfo = async (row: any) => {
    const data = await http.get(`paper/findById/${row.id}`);
    Object.keys(infoForm).forEach((item: any) => (infoForm[item] = data[item]));
    dialogInfo.value = true;
};

//详情弹窗->取消
const onInfoCancel = () => {
    dialogInfo.value = false;
};

//下载
const onDownload = async (id: string) => await http.export(`paper/download/${id}`);

//编辑
const onEdit = async (row: any) => {
    const data = await http.get(`paper/findById/${row.id}`);
    Object.keys(addForm).forEach((item: any) => (addForm[item] = data[item]));
    dialogEdit.value = true;
};

//编辑弹窗
const dialogEdit = ref<boolean>(false);

//编辑弹窗->提交
const onEditSubmit = async () => {
    if (!addFormRef.value) return;
    const status = await addFormRef.value?.validate((valid: any, _fields: any) => valid);
    if (status) {
        const data = await http.put("paper/update", addForm);
        if (data?.success) {
            emitter.emit("msg-success", data?.data);
            init();
            onEditCancel();
        }
    }
};

//编辑弹窗->取消
const onEditCancel = () => {
    dialogEdit.value = false;
};

//删除
const onDel = (row: any) => {
    box.confirm(`确定要删除<font color="red" style="font-weight:bold">${row.name}</font>吗？`, "删除", async () => {
        const data = await http.delete(`paper/deleteById/${row.id}`);
        if (data?.success) {
            emitter.emit("msg-success", data?.data);
            init();
        }
    });
};

//分页->改变分页数量
const onSizeChange = (val: number) => {
    page.pageNum = 1;
    page.pageSize = val;
    init();
};

//分页->改变页码
const onCurrentChange = (val: number) => {
    page.pageNum = val;
    init();
};

//AI生成试卷弹窗
const dialogPaperGenerate = ref<boolean>(false);

//是否展示提交按钮Submmit
const dialogPaperGenerateSubmitBtn = ref<boolean>(true);

//是否展示查看按钮
const dialogPaperGenerateInfoBtn = ref<boolean>(false);

//生成试卷弹窗
const onGeneratePaper = () => {
    dialogPaperGenerateInfoBtn.value = false;
    dialogPaperGenerateSubmitBtn.value = true;
    dialogPaperGenerate.value = true;
};

//生成试卷弹窗->表单
const paperGenerateFormRef = ref<any>(null);

//生成试卷提交
const onPaperGenerateSubmit = debounce(() => doPaperGenerateSubmit(), 200);

//执行生成试卷
const doPaperGenerateSubmit = () => {
    dialogPaperGenerateSubmitBtn.value = false;
    paperGenerateFormRef.value?.onSubmit();
};

//生成试卷取消
const onPaperGenerateCancel = debounce(() => doPaperGenerateCancel(), 100);

const doPaperGenerateCancel = () => {
    paperGenerateFormRef.value?.onCancel();
    dialogPaperGenerate.value = false;
};

//查看试卷
const onPaperGeneratePaperInfo = debounce(async () => doPaperGeneratePaperInfo(), 200);

const doPaperGeneratePaperInfo = async () => {};

//下载试卷
const onPaperGeneratePaperDownload = debounce(async () => doPaperGeneratePaperDownload(), 200);

const doPaperGeneratePaperDownload = async () => {};

//试卷生成完成
const onGenerateOver = () => {
    dialogPaperGenerateInfoBtn.value = true;
    dialogPaperGenerateSubmitBtn.value = false;
};

//初始化下拉框数据
const initSelect = async () => (classOptions.value = await http.get("paper/findClassSelect"));

//初始化
const init = async () => {
    const params = {
        ...page,
        desc: ["createTime"],
        param: {
            classId: searchFormModel.classId,
            name: { like: searchFormModel.name },
        },
    };
    data.value = await http.get("paper/page", params);
};

//挂载时并行执行
onMounted(() => {
    Promise.all([init(), initSelect()]);
});

//销毁时取消定时器
onUnmounted(() => {
    onExport.cancel();
    onPaperGeneratePaperInfo.cancel();
    onPaperGeneratePaperDownload.cancel();
    onPaperGenerateSubmit.cancel();
    onPaperGenerateCancel.cancel();
});
</script>

<style scoped lang="less">
@import "@/assets/less/common.less";
.upload-paper {
    width: 100%;
    :deep(.el-upload-dragger) {
        padding: 0 !important;
    }
}
.dialog-paper-download {
    color: #409eff;
    cursor: pointer;
}
.dialog-paper-download:hover {
    color: #79bbff;
    //cursor: pointer;
}
</style>
